home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 002 / emacssrc.arc / MAIN.C < prev    next >
Text File  |  1987-02-15  |  44KB  |  1,240 lines

  1. /*
  2.  *    MicroEMACS 3.8
  3.  *             written by Dave G. Conroy.
  4.  *            greatly modified by Daniel M. Lawrence
  5.  *
  6.  *    (C)opyright 1987 by Daniel M. Lawrence
  7.  *    MicroEMACS 3.8 can be copied and distributed freely for any
  8.  *    non-commercial purposes. MicroEMACS 3.8 can only be incorporated
  9.  *    into commercial software with the permission of the current author.
  10.  *
  11.  * This file contains the main driving routine, and some keyboard processing
  12.  * code, for the MicroEMACS screen editor.
  13.  *
  14.  * REVISION HISTORY:
  15.  *
  16.  * 1.0  Steve Wilhite, 30-Nov-85
  17.  *      - Removed the old LK201 and VT100 logic. Added code to support the
  18.  *        DEC Rainbow keyboard (which is a LK201 layout) using the the Level
  19.  *        1 Console In ROM INT. See "rainbow.h" for the function key defs
  20.  *      Steve Wilhite, 1-Dec-85
  21.  *      - massive cleanup on code in display.c and search.c
  22.  *
  23.  * 2.0  George Jones, 12-Dec-85
  24.  *      - Ported to Amiga.
  25.  *
  26.  * 3.0  Daniel Lawrence, 29-Dec-85
  27.  *      - rebound keys/added new fast buffered I/O for AMIGA
  28.  *    - added META- repeat commands
  29.  *    - added reposition default to center screen (yeah!)
  30.  *    - changed exit with modified buffers message
  31.  *    - made filesave tell us what it is doing
  32.  *    - changed search string entry to terminate with <ESC>
  33.  *      so we can use <NL> in search/replace strings
  34.  *    - updated version number in mode line to 3.0
  35.  *    12-Jan-86
  36.  *    - Added code to reconize the Search/replace functions
  37.  *    - Added code to perform search/replace & query functions
  38.  *    14-Jan-86
  39.  *    - moved search logic to separate function in search.c
  40.  *    - added replace and query replace functions
  41.  *    - separated out control key expansions to be used by others in search.c
  42.  *    15-Jan-86
  43.  *    - changed "visiting" to finding
  44.  *    - changed yes/no responces to not need return
  45.  *    - cleaned up various messages
  46.  *    16-jan-86
  47.  *    - fixed spurious spawn message in MSDOS
  48.  *    - added ^X-S synonime to save command
  49.  *    - moved escape to shell to ^X-C
  50.  *    21-jan-86
  51.  *    - added code to suspend shell under BSD
  52.  *    22-jan-86
  53.  *    - added function key support (SPEC) under MSDOS
  54.  *    - Abort now prints [Aborted] on message line
  55.  *    23-jan-86
  56.  *    - Added modes and commends to set/unset them
  57.  *    24-jan-86
  58.  *    - Added Goto Line command
  59.  *    - added Rename Buffer command
  60.  *    28-jan-86
  61.  *    - added goto beginning and end of paragraph commands (META-P/META-N)
  62.  *    - re-wrote kdelete to use realloc. gained MUCH speed here when
  63.  *      doing large wipes both on UNIX and MSDOS. Changed kill buffer
  64.  *      allocation block size from 256 bytes to 1 k
  65.  *    29-jan-86
  66.  *    - moved extern function declarations to efunc.h
  67.  *    - made name[] name binding table
  68.  *    30-jan-86
  69.  *    - fixed Previous/Next paragraph command not to wrap around EOF
  70.  *    - added Fill Paragraph command (META-Q)
  71.  *    4-feb-86
  72.  *    - added code to properly display long lines, scrolling them right
  73.  *      to left
  74.  *    5-feb-85
  75.  *    - rewrote code to right/left scroll...much better
  76.  *    - added shifted arror keys on IBMPC
  77.  *    6-feb-85
  78.  *    - add option to allow forword-word to jump to beginning of
  79.  *      next word instead of end of current one. This is different from
  80.  *      other emacs' but can be configured off in estruct.h
  81.  *    - added VIEW mode to allow a buffer to be read only
  82.  *       (-v switch on command line will activate this)
  83.  *    - changed quick exit to write out ALL changed buffers!!!
  84.  *      MAKE SURE YOU KNOW THIS WHEN META-Zing
  85.  *    10-feb-86
  86.  *    - added handling of lines longer than allowed on file read in
  87.  *      (they wrap on additional lines)
  88.  *    - made having space clear the message line and NOT insert itself
  89.  *      a configuration option in ed.h
  90.  *    11-feb-86
  91.  *    - added Describe-command and Help commands.
  92.  *    13-feb-86
  93.  *    - added View file command (^X ^V) and finished HELP command
  94.  *    14-feb-86
  95.  *    - added option to let main loop skip update if type ahead commands
  96.  *       are queued up
  97.  *    16-feb-86
  98.  *    - added Insert File command
  99.  *    17-feb-86
  100.  *    - added scroll next window up/down commands
  101.  *    18-feb-86
  102.  *    - added CMODE indentation
  103.  *    - re-arranged header files to standerdize extern and global
  104.  *      definitions
  105.  *    - changed version number to 3.2
  106.  *    - added numeric arguments to search, reverse search and
  107.  *      search and replace
  108.  *    24-feb-86
  109.  *    - added Bind To Key function (^C for now) to allow the user
  110.  *      to change his command keys
  111.  *    - added Unbind key function (M-^C for now)
  112.  *    - added execute named command to execute unbound commands (M-X)
  113.  *    - added describe bindings command (not bound)
  114.  *    - changed version number to 3.3
  115.  *    25-feb-86
  116.  *    - scrapped CERROR mode (too many compilers)
  117.  *    - added EXACT mode for case sensitive searchers
  118.  *    26-feb-86
  119.  *    - added command completion on execute named command and
  120.  *      all routined grabbing a command name
  121.  *    - adding execute-command-line command and its support functions
  122.  *      (in preporation for sourcing files)
  123.  *    - added Execute Buffer command
  124.  *    27-feb-86
  125.  *    - added execute(source) file command and added code to automatically
  126.  *      execute emacs.rc (or .emacsrc on UNIX) before initial read in
  127.  *    - changed version number to 3.4
  128.  *    4-mar-86
  129.  *    - changed word delete to be consistant with word move (it gets
  130.  *      rid of the inter word space now) This is configurable with the
  131.  *      NFWORD symbol in estruct.h
  132.  *    - added B_ACTIVE entry to the buffer table. Let emacs read multiple
  133.  *      file names from the command line and only read them in as needed
  134.  *    5-mar-85
  135.  *    - rewrote command line parser to get rid of my patchy code
  136.  *    - changed version number to 3.5
  137.  *    1-apr-86
  138.  *    - added support for Aztec C 3.20e under MSDOS
  139.  *    - fixed bug in mlwrite on ADM3's and thier ilk under V7
  140.  *    - added insertion of pounds in column one under CMODE
  141.  *    - changed version number to 3.6
  142.  *    3-apr-86
  143.  *    - added next-buffer command (^X-X)
  144.  *    5-apr-86
  145.  *    - added kill paragraph command (M-^W)
  146.  *    - changed fill-paragraph to leave 2 spaces after a period at the
  147.  *      end of a word.
  148.  *    - added OVERWRITE mode
  149.  *    7-apr-86
  150.  *    - fixed overwrite mode to handle tabs
  151.  *    8-apr-86
  152.  *    - added add/delete global mode (<ESC>M & <ESC> ^M) commands
  153.  *    9-apr-86
  154.  *    - added insert space command
  155.  *    - moved bindings around        ^C    insert space
  156.  *                    M-K    bind-to-key
  157.  *                    INSERT    insert space
  158.  *                    DELETE    forwdel
  159.  *    - added hunt forward and hunt reverse commands
  160.  *    10-apr-86
  161.  *    - fixed bug in DOBUF with non-terminated command string
  162.  *    15-apr-86
  163.  *    - fixed tab expansion bug in DISPLAY which hung the AMIGA
  164.  *      (send in by Dawn Banks)
  165.  *    - fixed curcol problen if forwline/backline during keyboard
  166.  *      macro execution (sent in by Ernst Christen)
  167.  *    - added AMIGA function/cursor key support
  168.  *    - fixed nonterminating <NL> replacement bug
  169.  *    - fixed word wrapping problems
  170.  *    16-apr-86
  171.  *    - updated documentation and froze development for 3.6 net release
  172.  *    23-apr-86    version 3.6a
  173.  *    - added forground and background colors. Setable with the
  174.  *      add mode commands for the moment
  175.  *    24-apr-86
  176.  *    - added command to pipe CLI output to a buffer
  177.  *    25-apr-86
  178.  *    - added Dana Hoggat's code to replace lattice's sick system()
  179.  *      function, now we no longer care what the switchar is.
  180.  *    - cleaned up the positioning on several of the spawing commands
  181.  *    26-apr-86
  182.  *    - added a output flush in vttidy(). Unix really appreciates this.
  183.  *    - added filter-buffer (^X#) command to send a buffer through
  184.  *      a dos filter
  185.  *    - made automatic CMODE on .c and .h file compilation dependant
  186.  *      in estruct.h
  187.  *    1-may-86
  188.  *    - optimized some code in update(). It certainly need a lot more.
  189.  *    - added AZTEC profiling capabilities. These are conditional on
  190.  *      the APROF symbol in estruct.h
  191.  *    2-may-86
  192.  *    - added (u)ndo command in query-replace. undoes last repalce.
  193.  *    6-may-86
  194.  *    - re-orginized and wrote the update() function in display.c
  195.  *      now my color hacks are in the right places and the code can be
  196.  *      understood.
  197.  *    [Released version 3.6f for BETA test sites]
  198.  *    8-may-86
  199.  *    - fixed bug in new display routine to wrap cursor on extended
  200.  *      lines at the right time
  201.  *    - modified the buffer-position command to give reasonable info
  202.  *    9-may-86
  203.  *    - improved the word wrap algorithm as not to discard non-space
  204.  *      delimiters. The backscan now looks for white space rather than
  205.  *      !inword().
  206.  *    [Released version 3.6g to Krannert]
  207.  *    10-may-86
  208.  *    - Added IBMPC.C an IBM-PC specific display driver. This makes paging
  209.  *      4-6 times faster. Also made some conditional changes to DISPLAY.C
  210.  *      to eliminate the pscreen[] if using the PC driver.
  211.  *    [changed version number to 3.6i]
  212.  *    12-may-86
  213.  *    - added delete-window (^X 0) command to dispose of a single window
  214.  *    - fixed problem with multiple prefixes from a command line which
  215.  *      was reported by John Gamble
  216.  *    14-may-86
  217.  *    - Added AZTEC support for the IBMPC display driver. Had to
  218.  *      readjust some includes and defines for this.
  219.  *    - fixed bug in delete-window.
  220.  *    - fixed some bizarre behavior with the cursor after coming back
  221.  *      from spawn calls.
  222.  *    [changed version number to 3.7 Freezing development for net release]
  223.  *    15-may-86
  224.  *    - (that didn't last long...) Added execute-macro-(1 thru 20) commands
  225.  *      to execute macro buffers (named "[Macro nn]")
  226.  *    - changed BFTEMP to BFINVS and cleaned up treatment of invisable
  227.  *      buffers.
  228.  *    16-may-86
  229.  *    - added store-macro (unbound) to store any executed command lines to
  230.  *      macro buffer.
  231.  *    - added clear-message-line (unbound) command to do just that
  232.  *    - added resize-window command to change a window's size to the
  233.  *      specified argument
  234.  *    - improved help's logic not to re-read the file if it was already
  235.  *      in a buffer
  236.  *    - added MAGIC mode to all structures and command tables, but the
  237.  *      regular expression code that John Gamble is writting is not ready.
  238.  *    18-may-86
  239.  *    - added interactive prompt requests in command line execution. IE
  240.  *      while executing a macro, a parameter starting with an at sign (@)
  241.  *      causes emacs to prompt with the rest of the parameter and return
  242.  *      the resulting input as the value of the parameter.
  243.  *    - added arguments to split-current-window to force the cursor into
  244.  *      the upper or lower window.
  245.  *    20-may-86
  246.  *    - added support for the Microsoft C compiler as per the changes
  247.  *      send in by Oliver Sharp
  248.  *    - made some upgrades and fixes for VMS sent in by Guy Streeter
  249.  *    21-may-86
  250.  *    - fixed an AZTEC bug in ttgetc by clearing the upper byte
  251.  *    - fixed buf in CMODE with #preprocesser input (bug fix submitted by
  252.  *      Willis of unknown path)
  253.  *    - added support of alternative startup file ( @<filename> ) in
  254.  *      the command line
  255.  *    - added ^Q quoting in interactive input (mlreplyt()).
  256.  *    - added re-binding of meta-prefix and ctlx-prefix
  257.  *    22-may-86
  258.  *    - reorginize getkey routines to make more sense and let prefix
  259.  *      binding work properly.
  260.  *    23-may-86
  261.  *    - checked new code on BSD4.2 made a few fixes
  262.  *    - added optional fence matching while in CMODE
  263.  *    - added goto and search command line arguments by Mike Spitzer
  264.  *    26-may-86
  265.  *    - added parameter fetching from buffers
  266.  *    27-may-86
  267.  *    - fixed some HP150 bugs......
  268.  *    31-may-86
  269.  *    - Added Wang PC keyboard support from modifications by
  270.  *      Sid Shapiro @ Wang Institute
  271.  *    - Fixed some reverse video bugs with code submitted by Peter Chubb
  272.  *    - Fixed bug in nextbuffer reported by Dave Forslund
  273.  *    - added system V support (USG) from Linwood Varney
  274.  *    2-jun-86
  275.  *    - changed defines to just define one unix define (for example,
  276.  *      just define BSD for Unix BSD 4.2)
  277.  *    - Added Incremental search functions written by D. R. Banks
  278.  *      in file ISEARCH.C
  279.  *    - added insert-string (unbound) command to help the macro
  280.  *      language out.
  281.  *    - added unmark-buffer (M-~) command to turn off the current buffers
  282.  *      change flag
  283.  *    - fixed nxtarg to truncate strings longer than asked for max length
  284.  *    4-jun-86
  285.  *    - added special characters in command line tokens. Tidle (~) is
  286.  *      the special leadin character for "nrtb".
  287.  *    - Fixed bad ifdef in aztec code so it could look at HOME dir
  288.  *      for startup, help, and emacs.rc files
  289.  *    6-jun-86
  290.  *    - make delete word commands clear the kill buffer if not after another
  291.  *      kill command
  292.  *    11-jun-86
  293.  *    - made ~@ in string arguments pass as char(192) to nxtarg() so one can
  294.  *      quote @ at the beginning of string arguments
  295.  *    - changed buffer size vars in listbuffers() to long (for big files)
  296.  *    - re-wrote buffer-position command to be much faster
  297.  *    12-jun-86
  298.  *    - added count-words (M-^C) command to count the words/chars and
  299.  *      lines in a region
  300.  *    - changed regions so they could be larger than 65535 (short ->
  301.  *      long in the REGION structure)
  302.  *    - changed ldelete() and all callers to use a long size. The kill
  303.  *      buffer will still have a problem >65535 that can not be solved
  304.  *      until I restructure it.
  305.  *    - grouped paragraph commands and word count together under symbol
  306.  *      WORDPRO to allow them to be conditionally made (or not)
  307.  *    13-jun-86
  308.  *    - re-wrote kill buffer routines again. Now they support an unlimited
  309.  *      size kill buffer, and are (in theory) faster.
  310.  *    - changed delete-next-word (M-D) to not eat the newline after a word,
  311.  *      instead it checks and eats a newline at the cursor.
  312.  *    17-jun-85
  313.  *    - added numeric argument to next/previous-window to access the nth
  314.  *      window from the top/bottom
  315.  *    - added support for the data General 10 MSDOS machine
  316.  *    - added save-window (unbound) and restore-window (unbound) commands
  317.  *      for the use of the menu script. Save-window remembers which window
  318.  *      is current, and restore-window returns the cursor to that window.
  319.  *    20-jun-86
  320.  *    - fixed a bug with the fence matching locking up near the beginning
  321.  *    of a buffer
  322.  *    - added argument to update to selectivaly force a complete update
  323.  *    - added update-screen (unbound) command so macros can force a
  324.  *      screen update
  325.  *    21-jun-86
  326.  *    - rearranged token() and nxtarg() calls so that command names and
  327.  *      repeat counts could also be prompted and fetched from buffers
  328.  *      [this broke later with the exec re-write....]
  329.  *    - added write-message (unbound) command to write out a message
  330.  *      on the message line (for macros)
  331.  *    - changed ifdef's so that color modes are reconized as legal in
  332.  *      b/w version, and simply do nothing (allowing us to use the same
  333.  *      script files)
  334.  *    [Released version 3.7 on July 1 to the net and elswhere]
  335.  *    2-jul-86
  336.  *    - Changed search string terminator to always be the meta character
  337.  *      even if it is rebound.
  338.  *    3-jul-86
  339.  *    - removed extra calls to set color in startup code. This caused the
  340.  *      original current window always to be the global colors.
  341.  *    7-jul-86
  342.  *    - Fixed bugs in mlreplyt() so to work properly with all terminators
  343.  *      including control and spec characters
  344.  *    22-jul-86
  345.  *    - fixed replaces() so that it will return FALSE properly on the
  346.  *      input of the replacement string.
  347.  *    - added a definition for FAILED as a return type.....
  348.  *    - changed version number to 3.7b
  349.  *    23-jul-86
  350.  *    - fixed o -> 0 problem in termio.c
  351.  *    - made ^U universal-argument re-bindable
  352.  *    - wrote atoi() for systems (like aztec) where it acts screwy
  353.  *    - changed version number to 3.7c
  354.  *    25-jul-86
  355.  *    - make ^G abort-command rebindable
  356.  *    29-jul-86
  357.  *    - added HP110 Portable Computer support
  358.  *    - changed version number to 3.7d
  359.  *    30-jul-86
  360.  *    - Fixed a couple of errors in the new VMS code as pointer
  361.  *      out by Ken Shacklford
  362.  *    - split terminal open/close routines into screen and keyboard
  363.  *      open/close routines
  364.  *    - closed the keyboard during all disk I/O so that OS errors
  365.  *      can be respoded to correctly (especially on the HP150)
  366.  *    - changed version number to 3.7e
  367.  *    31-jul-86
  368.  *    - added label-function-key (unbound) command under symbol FLABEL
  369.  *      (primarily for the HP150)
  370.  *    4-aug-86
  371.  *    - added fixes for MicroSoft C as suggested by ihnp4!ihuxm!gmd1
  372.  *        <<remember to fix [list] deletion bug as reported
  373.  *          by craig@hp-pcd>>
  374.  *    8-aug-86
  375.  *    - fixed beginning misspelling error everywhere
  376.  *    - fixed some more MSC errors
  377.  *    - changed version number to 3.7g
  378.  *    20-aug-86
  379.  *    - fixed CMODE .h scanning bug
  380.  *    - changed version number to 3.7h
  381.  *    30-aug-86
  382.  *    - fixed killing renamed [list] buffer (it can't) as submited
  383.  *      by James Aldridge
  384.  *    - Added code to allow multiple lines to display during
  385.  *      vertical retrace
  386.  *      [total disaster....yanked it back out]
  387.  *    9-sep-86
  388.  *    - added M-A (apropos) command to list commands containing a substring.
  389.  *    - fixed an inefficiency in the display update code submited
  390.  *      by William W. Carlson (wwc@pur-ee)
  391.  *    10-sep-86
  392.  *    - added Dana Hoggatt's code for encryption and spliced it into the
  393.  *      proper commands. CRYPT mode now triggers encryption.
  394.  *    - added -k flag to allow encryption key (no spaces) in command line
  395.  *    14-sep-86
  396.  *    - added missing lastflag/thisflag processing to docmd()
  397.  *    - changed version to 3.7i and froze for partial release via mail
  398.  *      and BBS
  399.  *    05-oct-86
  400.  *    - changed some strcpys in main.c to strncpys as suggested by john
  401.  *      gamble
  402.  *    - replaces search.c and isearch.c with versions modified by
  403.  *      john gamble
  404.  *    10-oct-86
  405.  *    - removed references to lflick....it just won't work that way.
  406.  *    - removed defines LAT2 and LAT3...the code no longer is lattice
  407.  *      version dependant.
  408.  *    14-oct-86
  409.  *    - changed spawn so that it will not not pause if executed from
  410.  *      a command line
  411.  *    15-oct-86
  412.  *    - added argument concatination (+) to the macro parsing
  413.  *    - added [] as fence pairs
  414.  *    16-oct-86
  415.  *    - rewrote all macro line parsing routines and rearranged the
  416.  *      mlreply code. saved .6K!!! and have blazed the path for expanding
  417.  *      the command language.
  418.  *    17-oct-86
  419.  *    - added new keyboard macro routines (plus a new level to the
  420.  *      input character function)
  421.  *    22-oct-86
  422.  *    - improved EGA cursor problems
  423.  *    - added -r (restricted) switch to command line for BBS use
  424.  *    06-nov-86
  425.  *    - fixed terminator declarations from char to int in getarg() and
  426.  *      nxtarg() in exec.c as pointed out by john gamble
  427.  *    07-nov-86
  428.  *    - made wordrap() user callable as wrap-word (M-FNW) and changed
  429.  *      the getckey() routine so that illegal keystrokes (too many
  430.  *      prefixes set) could be used for internal bindings. When word
  431.  *      wrap conditions are met, the keystroke M-FNW is executed. Added
  432.  *      word wrap check/call to newline().
  433.  *    11-nov-86
  434.  *    - added and checked support for Mark Williams C 86
  435.  *    12-nov-86
  436.  *    - added goto-matching-fence (M-^F) command to jump to a matching
  437.  *      fence "({[]})" or beep if there is none. This can reframe the
  438.  *      screen.
  439.  *    - added code and structure elements to support change-screen-size
  440.  *      command (M-^S) to change the number of lines being used by
  441.  *      MicroEMACS.
  442.  *    15-nov-86
  443.  *    - finished debuging change-screen-size
  444.  *    17-nov-86
  445.  *    - Encorporated in James Turner's modifications for the Atari ST
  446.  *        23-sep-86
  447.  *        - added support for the Atari ST line of computers (jmt)
  448.  *        --added a '\r' to the end of each line on output and strip
  449.  *          it on input for the SHOW function from the desktop
  450.  *        --added 3 new mode functions (HIREZ, MEDREZ, and LOREZ); chgrez
  451.  *          routine in TERM structure; and MULTREZ define in estructs.h
  452.  *          to handle multiple screen resolutions
  453.  *    [note....ST still not running under lattice yet...]
  454.  *    25-nov-86
  455.  *    - Made the filter-buffer (^X-#) command not work on VIEW mode
  456.  *      buffers
  457.  *    - Made the quick-exit (M-Z) command throw out a newline after 
  458.  *      each message so they could be seen.
  459.  *    26-nov-86
  460.  *    - fixed a couple of bugs in change-screen-size (M-^S) command
  461.  *    - changed file read behavior on long lines and last lines
  462.  *      with no newline (it no longer throws the partial line out)
  463.  *    - [as suggested by Dave Tweten] Made adding a ^Z to the end
  464.  *      of an output file under MSDOS configurable under the
  465.  *      CTRLZ symbol in estruct.h
  466.  *    - [Dave Tweten] Spawn will look up the "TMP" environment variable
  467.  *      for use during various pipeing commands.
  468.  *    - [Dave Tweten] changed pipe command under MSDOS to use '>>'
  469.  *      instead of '>'
  470.  *    04-dec-86
  471.  *    - moved processing of '@' and '#' so that they can be outside
  472.  *      the quotes in an argument, and added hooks to process '%' for
  473.  *      environment and user variables.
  474.  *    - modified ibmpc.c to sence the graphics adapter (CGA and MONO)
  475.  *      at runtime to cut down on the number of versions.
  476.  *    05-dec-86
  477.  *    - changed macro directive character to "!" instead of "$" (see
  478.  *      below) and fixed the standard .rc file to comply.
  479.  *    - added code to interpret environment variables ($vars). Added
  480.  *      hooks for built in functions (&func). So, to recap:
  481.  *
  482.  *        @<string>    prompt and return a string from the user
  483.  *        #<buffer name>    get the next line from a buffer and advance
  484.  *        %<var>        get user variable <var>
  485.  *        $<evar>        get environment variable <evar>
  486.  *        &<func>        evaluate function <func>
  487.  *
  488.  *    - allowed repeat counts to be any of the above
  489.  *    - added code to allow insert-string (unbound) to use its
  490.  *      repeat count properly
  491.  *    - added set (^X-A) command to set variables. Only works on
  492.  *      environmental vars yet.
  493.  *    9-dec-86
  494.  *    - added some code for user defined variables...more to come
  495.  *    - added options for malloc() memory pool tracking
  496.  *    - preliminary user variables (%) working
  497.  *    - changed terminal calls to macro's (to prepare for the new
  498.  *      terminal drivers)
  499.  *    15-dec-86
  500.  *    - changed previous-line (^P) and next-line (^N) to return a
  501.  *      FALSE at the end or beginning of the file so repeated
  502.  *      macros involving them terminate properly!
  503.  *    - added code for $CURCOL and $CURLINE
  504.  *    20-dec-86
  505.  *    - set (^X-A) now works with all vars
  506.  *    - added some new functions
  507.  *          &ADD &SUB &TIMES &DIV &MOD &NEG &CAT
  508.  *    - yet again rearranged functions to control macro execution. Did
  509.  *      away with getarg()
  510.  *    23-dec-86
  511.  *    - added string functions
  512.  *          &LEFt &RIGht &MID
  513.  *    31-dec-86
  514.  *    - added many logical functions
  515.  *          &NOT &EQUal &LESs &GREater
  516.  *    - added string functions
  517.  *          &SEQual &SLEss &SGReater
  518.  *    - added variable indirection with &INDirect
  519.  *    - made fixes to allow recursive macro executions
  520.  *      (improved speed during macro execution as well)
  521.  *    3-jan-87
  522.  *    - added $FLICKER to control flicker supression
  523.  *    - made spawn commands restricted
  524.  *    - cleaned up lots of unintentional int<->char problems
  525.  *    4-jan-87
  526.  *    - Fixed broken pipe-command (^X-@) command under MSDOS
  527.  *    - added !IF  !ELSE  !ENDIF  directives and changed the
  528.  *      name of !END to !ENDM....real slick stuff
  529.  *    5-jan-87
  530.  *    - quick-exit (M-Z) aborts on any filewrite errors
  531.  *    8-jan-87
  532.  *    - debugged a lot of the new directive and evaluation code.
  533.  *      BEWARE of stack space overflows! (increasing stack to
  534.  *      16K under MSDOS)
  535.  *    - removed non-standard DEC Rainbow keyboard support...let someone
  536.  *      PLEASE impliment this in the standard manner using key bindings
  537.  *      and send the results to me.
  538.  *    - added change-screen-width () command and $CURWIDTH variable
  539.  *    11-jan-87
  540.  *    - fixed an increadably deeply buried bug in vtputc and combined
  541.  *      it with vtpute (saving about 200 bytes!)
  542.  *    16-jan-87
  543.  *    - added code to handle controling multiple screen resolutions...
  544.  *      allowed the IBM-PC driver to force mono or cga modes.
  545.  *    - added current buffer name and filename variables
  546.  *      $cbufname and $cfname
  547.  *    18-jan-87
  548.  *    - added $sres variable to control screen resolution
  549.  *    - added $debug variable to control macro debugging code (no longer
  550.  *      is this activated by GLOBAL spell mode)
  551.  *    - fixed bug in -g command line option
  552.  *    - Released Version 3.8 to BBSNET
  553.  *    21-jan-87
  554.  *    - added $status variable to record return status of last command
  555.  *    2-feb-87
  556.  *    - added ATARI 1040 support...runs in all three modes right now
  557.  *    - added $palette var with palette value in it
  558.  *    - undefined "register" in bind.c and input.c for ST520 & LATTICE
  559.  *      to get around a nasty lattice bug
  560.  *    4-feb-87
  561.  *    - added, debugged code for switching all 1040ST color modes, added
  562.  *      code for HIGH monochrome mode as well, DENSE still pending
  563.  *    5-feb-87
  564.  *    - with John Gamble, found and corrected the infamous bad matching
  565.  *      fence problems.
  566.  *    - added error return check in various add/delete mode commands
  567.  *    10-feb-87
  568.  *    - re-arrange code in docmd() so that labels are stored in
  569.  *      macro buffers
  570.  *    - fixed !RETURN to only return if (execlevel == 0) [If we are
  571.  *      currently executing]
  572.  *    14-feb-86
  573.  *    - added to outp() calls in the EGA driver to fix a bug in the BIOS
  574.  *    - adding code for 1040ST 40 line DENSE mode
  575.  */
  576.  
  577. #include        <stdio.h>
  578.  
  579. /* for MSDOS, increase the default stack space */
  580.  
  581. #if    MSDOS & LATTICE
  582. unsigned _stack = 16536;
  583. #endif
  584.  
  585. #if    MSDOS & AZTEC
  586. int _STKSIZ = 16536/16;        /* stack size in paragraphs */
  587. int _STKRED = 1024;        /* stack checking limit */
  588. int _HEAPSIZ = 4096/16;        /* (in paragraphs) */
  589. int _STKLOW = 0;        /* default is stack above heap (small only) */
  590. #endif
  591.  
  592. /* make global definitions not external */
  593. #define    maindef
  594.  
  595. #include        "estruct.h"    /* global structures and defines */
  596. #include    "efunc.h"    /* function declarations and name table    */
  597. #include    "edef.h"    /* global definitions */
  598. #include    "ebind.h"    /* default key bindings */
  599.  
  600. #if     VMS
  601. #include        <ssdef.h>
  602. #define GOOD    (SS$_NORMAL)
  603. #endif
  604.  
  605. #ifndef GOOD
  606. #define GOOD    0
  607. #endif
  608.  
  609. #if    APROF    /* Declarations needed for AZTEC C profiling */
  610. int _Corg();    /* first address of program */
  611. int _Cend();    /* last address of program */
  612.  
  613. short monbuf[NBUCK];    /* buffer for gather info */
  614. #endif
  615.  
  616. main(argc, argv)
  617. char    *argv[];
  618. {
  619.         register int    c;
  620.         register int    f;
  621.         register int    n;
  622.         register int    mflag;
  623.     register BUFFER *bp;
  624.     register int    ffile;        /* first file flag */
  625.     register int    carg;        /* current arg to scan */
  626.     register int    startf;        /* startup executed flag */
  627.     int basec;            /* c stripped of meta character */
  628.     int viewflag;            /* are we starting in view mode? */
  629.         int gotoflag;                   /* do we need to goto a line at start? */
  630.         int gline;                      /* if so, what line? */
  631.         int searchflag;                 /* Do we need to search at start? */
  632.         char bname[NBUFN];        /* buffer name of file to read */
  633. #if    CRYPT
  634.     int eflag;            /* encrypting on the way in? */
  635.     char ekey[NPAT];        /* startup encryption key */
  636. #endif
  637.  
  638. #if    APROF
  639.     /* if we are doing AZTEC C profiling, start it up */
  640.     /*_intr_sp(18);     set clock interupt for 60/second */
  641.     monitor(_Corg, _Cend, monbuf, NBUCK, 0);
  642. #endif
  643.  
  644.     /* initialize the editor and process the command line arguments */
  645.         strcpy(bname, "main");    /* default buffer name */
  646.         vtinit();        /* Displays.            */
  647.         edinit(bname);        /* Buffers, windows.    */
  648.     varinit();        /* user variables */
  649.     viewflag = FALSE;    /* view mode defaults off in command line */
  650.     gotoflag = FALSE;    /* set to off to begin with */
  651.     searchflag = FALSE;    /* set to off to begin with */
  652.     ffile = TRUE;        /* no file to edit yet */
  653.     startf = FALSE;        /* startup file not executed yet */
  654. #if    CRYPT
  655.     eflag = FALSE;        /* no encryption by default */
  656. #endif
  657. #if    COLOR
  658.     curwp->w_fcolor = gfcolor;        /* and set colors    */
  659.     curwp->w_bcolor = gbcolor;
  660. #endif
  661.     
  662.     /* scan through the command line and get the files to edit */
  663.     for (carg = 1; carg < argc; ++carg) {
  664.         /* if its a switch, process it */
  665.         if (argv[carg][0] == '-') {
  666.             switch (argv[carg][1]) {
  667.                 case 'v':    /* -v for View File */
  668.                 case 'V':
  669.                     viewflag = TRUE;
  670.                     break;
  671.                 case 'e':    /* -e for Edit file */
  672.                 case 'E':
  673.                     viewflag = FALSE;
  674.                     break;
  675.                 case 's':    /* -s for initial search string */
  676.                 case 'S':
  677.                     searchflag = TRUE;
  678.                     strncpy(pat,&argv[carg][2],NPAT);
  679.                     break;
  680.                 case 'g':    /* -g for initial goto */
  681.                 case 'G':    
  682.                     gotoflag = TRUE;
  683.                     gline = atoi(&argv[carg][2]);
  684.                     break;
  685.                 case 'r':    /* -r restrictive use */
  686.                 case 'R':
  687.                     restflag = TRUE;
  688.                     break;
  689. #if    CRYPT
  690.                 case 'k':    /* -k<key> for code key */
  691.                 case 'K':
  692.                     if (argv[carg][2] == 0)
  693.                         eflag = FALSE;
  694.                     else {
  695.                         eflag = TRUE;
  696.                         strcpy(ekey, &argv[carg][2]);
  697.                     }
  698.                     break;
  699. #endif
  700.                 default:    /* unknown switch */
  701.                     /* ignore this for now */
  702.                     break;
  703.             }
  704.         } else     /* check for a macro file */
  705.             if (argv[carg][0]== '@') {
  706.  
  707.             if (startup(&argv[carg][1]) == TRUE)
  708.                 startf = TRUE;    /* don't execute emacs.rc */
  709.  
  710.         } else {    /* process a file name */
  711.             /* if we haven't run emacs.rc, do it now */
  712.             if (startf == FALSE) {
  713.                 startup("");
  714.                 startf = TRUE;
  715. #if    COLOR
  716.                 curwp->w_fcolor = gfcolor;
  717.                 curwp->w_bcolor = gbcolor;
  718. #endif
  719.             }
  720.  
  721.             /* set up a buffer for this file */
  722.                     makename(bname, argv[carg]);
  723.  
  724. #if    CRYPT
  725.             /* set up for de-cryption if needed */
  726.             if (eflag) {
  727.                 curbp->b_mode |= MDCRYPT;
  728.                 strncpy(curbp->b_key, ekey, NPAT);
  729.                 crypt((char *)NULL, 0);
  730.                 crypt(curbp->b_key, strlen(curbp->b_key));
  731.             }
  732. #endif
  733.  
  734.             /* if this is the first file, read it in */
  735.             if (ffile) {
  736.                 bp = curbp;
  737.                 makename(bname, argv[carg]);
  738.                 strcpy(bp->b_bname, bname);
  739.                 strcpy(bp->b_fname, argv[carg]);
  740.                 if (readin(argv[carg], (viewflag==FALSE))
  741.                                 == ABORT) {
  742.                     strcpy(bp->b_bname, "main");
  743.                     strcpy(bp->b_fname, "");
  744.                 }
  745.                 bp->b_dotp = bp->b_linep;
  746.                 bp->b_doto = 0;
  747.                 ffile = FALSE;
  748.             } else {
  749.                 /* set this to inactive */
  750.                 bp = bfind(bname, TRUE, 0);
  751.                 strcpy(bp->b_fname, argv[carg]);
  752.                 bp->b_active = FALSE;
  753.             }
  754.  
  755.             /* set the view mode appropriatly */
  756.             if (viewflag)
  757.                 bp->b_mode |= MDVIEW;
  758.         }
  759.     }
  760.  
  761.     /* if invoked with nothing, run the startup file here */
  762.     if (startf == FALSE) {
  763.         startup("");
  764.         startf = TRUE;
  765. #if    COLOR
  766.         curwp->w_fcolor = gfcolor;
  767.         curwp->w_bcolor = gbcolor;
  768. #endif
  769.     }
  770.  
  771.         /* Deal with startup gotos and searches */
  772.  
  773.         if (gotoflag && searchflag) {
  774.             update(FALSE);
  775.         mlwrite("[Can not search and goto at the same time!]");
  776.     }
  777.         else if (gotoflag) {
  778.                 if (gotoline(TRUE,gline) == FALSE) {
  779.                     update(FALSE);
  780.             mlwrite("[Bogus goto argument]");
  781.         }
  782.         } else if (searchflag) {
  783.                 if (forwhunt(FALSE, 0) == FALSE)
  784.                     update(FALSE);
  785.         }
  786.  
  787.     /* setup to process commands */
  788.         lastflag = 0;                           /* Fake last flags.     */
  789.     curbp->b_mode |= gmode;            /* and set default modes*/
  790.     curwp->w_flag |= WFMODE;        /* and force an update    */
  791.  
  792. loop:
  793.         update(FALSE);                          /* Fix up the screen    */
  794.         c = getcmd();
  795.         if (mpresf != FALSE) {
  796.                 mlerase();
  797.                 update(FALSE);
  798. #if    CLRMSG
  799.                 if (c == ' ')                   /* ITS EMACS does this  */
  800.                         goto loop;
  801. #endif
  802.         }
  803.         f = FALSE;
  804.         n = 1;
  805.  
  806.     /* do META-# processing if needed */
  807.  
  808.     basec = c & ~META;        /* strip meta char off if there */
  809.     if ((c & META) && ((basec >= '0' && basec <= '9') || basec == '-')) {
  810.         f = TRUE;        /* there is a # arg */
  811.         n = 0;            /* start with a zero default */
  812.         mflag = 1;        /* current minus flag */
  813.         c = basec;        /* strip the META */
  814.         while ((c >= '0' && c <= '9') || (c == '-')) {
  815.             if (c == '-') {
  816.                 /* already hit a minus or digit? */
  817.                 if ((mflag == -1) || (n != 0))
  818.                     break;
  819.                 mflag = -1;
  820.             } else {
  821.                 n = n * 10 + (c - '0');
  822.             }
  823.             if ((n == 0) && (mflag == -1))    /* lonely - */
  824.                 mlwrite("Arg:");
  825.             else
  826.                 mlwrite("Arg: %d",n * mflag);
  827.  
  828.             c = getcmd();    /* get the next key */
  829.         }
  830.         n = n * mflag;    /* figure in the sign */
  831.     }
  832.  
  833.     /* do ^U repeat argument processing */
  834.  
  835.         if (c == reptc) {                  /* ^U, start argument   */
  836.                 f = TRUE;
  837.                 n = 4;                          /* with argument of 4 */
  838.                 mflag = 0;                      /* that can be discarded. */
  839.                 mlwrite("Arg: 4");
  840.                 while ((c=getcmd()) >='0' && c<='9' || c==reptc || c=='-'){
  841.                         if (c == reptc)
  842.                 if ((n > 0) == ((n*4) > 0))
  843.                                     n = n*4;
  844.                             else
  845.                                 n = 1;
  846.                         /*
  847.                          * If dash, and start of argument string, set arg.
  848.                          * to -1.  Otherwise, insert it.
  849.                          */
  850.                         else if (c == '-') {
  851.                                 if (mflag)
  852.                                         break;
  853.                                 n = 0;
  854.                                 mflag = -1;
  855.                         }
  856.                         /*
  857.                          * If first digit entered, replace previous argument
  858.                          * with digit and set sign.  Otherwise, append to arg.
  859.                          */
  860.                         else {
  861.                                 if (!mflag) {
  862.                                         n = 0;
  863.                                         mflag = 1;
  864.                                 }
  865.                                 n = 10*n + c - '0';
  866.                         }
  867.                         mlwrite("Arg: %d", (mflag >=0) ? n : (n ? -n : -1));
  868.                 }
  869.                 /*
  870.                  * Make arguments preceded by a minus sign negative and change
  871.                  * the special argument "^U -" to an effective "^U -1".
  872.                  */
  873.                 if (mflag == -1) {
  874.                         if (n == 0)
  875.                                 n++;
  876.                         n = -n;
  877.                 }
  878.         }
  879.  
  880.     /* and execute the command */
  881.         execute(c, f, n);
  882.         goto loop;
  883. }
  884.  
  885. /*
  886.  * Initialize all of the buffers and windows. The buffer name is passed down
  887.  * as an argument, because the main routine may have been told to read in a
  888.  * file by default, and we want the buffer name to be right.
  889.  */
  890. edinit(bname)
  891. char    bname[];
  892. {
  893.         register BUFFER *bp;
  894.         register WINDOW *wp;
  895.     char *malloc();
  896.  
  897.         bp = bfind(bname, TRUE, 0);             /* First buffer         */
  898.         blistp = bfind("[List]", TRUE, BFINVS); /* Buffer list buffer   */
  899.         wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window         */
  900.         if (bp==NULL || wp==NULL || blistp==NULL)
  901.                 exit(1);
  902.         curbp  = bp;                            /* Make this current    */
  903.         wheadp = wp;
  904.         curwp  = wp;
  905.         wp->w_wndp  = NULL;                     /* Initialize window    */
  906.         wp->w_bufp  = bp;
  907.         bp->b_nwnd  = 1;                        /* Displayed.           */
  908.         wp->w_linep = bp->b_linep;
  909.         wp->w_dotp  = bp->b_linep;
  910.         wp->w_doto  = 0;
  911.         wp->w_markp = NULL;
  912.         wp->w_marko = 0;
  913.         wp->w_toprow = 0;
  914. #if    COLOR
  915.     /* initalize colors to global defaults */
  916.     wp->w_fcolor = gfcolor;
  917.     wp->w_bcolor = gbcolor;
  918. #endif
  919.         wp->w_ntrows = term.t_nrow-1;           /* "-1" for mode line.  */
  920.         wp->w_force = 0;
  921.         wp->w_flag  = WFMODE|WFHARD;            /* Full.                */
  922. }
  923.  
  924. /*
  925.  * This is the general command execution routine. It handles the fake binding
  926.  * of all the keys to "self-insert". It also clears out the "thisflag" word,
  927.  * and arranges to move it to the "lastflag", so that the next command can
  928.  * look at it. Return the status of command.
  929.  */
  930. execute(c, f, n)
  931. {
  932.         register KEYTAB *ktp;
  933.         register int    status;
  934.  
  935.         ktp = &keytab[0];                       /* Look in key table.   */
  936.         while (ktp->k_fp != NULL) {
  937.                 if (ktp->k_code == c) {
  938.                         thisflag = 0;
  939.                         status   = (*ktp->k_fp)(f, n);
  940.                         lastflag = thisflag;
  941.                         return (status);
  942.                 }
  943.                 ++ktp;
  944.         }
  945.  
  946.         /*
  947.          * If a space was typed, fill column is defined, the argument is non-
  948.          * negative, wrap mode is enabled, and we are now past fill column,
  949.      * and we are not read-only, perform word wrap.
  950.          */
  951.         if (c == ' ' && (curwp->w_bufp->b_mode & MDWRAP) && fillcol > 0 &&
  952.         n >= 0 && getccol(FALSE) > fillcol &&
  953.         (curwp->w_bufp->b_mode & MDVIEW) == FALSE)
  954.         execute(META|SPEC|'W', FALSE, 1);
  955.  
  956.         if ((c>=0x20 && c<=0x7E)                /* Self inserting.      */
  957.         ||  (c>=0xA0 && c<=0xFE)) {
  958.                 if (n <= 0) {                   /* Fenceposts.          */
  959.                         lastflag = 0;
  960.                         return (n<0 ? FALSE : TRUE);
  961.                 }
  962.                 thisflag = 0;                   /* For the future.      */
  963.  
  964.         /* if we are in overwrite mode, not at eol,
  965.            and next char is not a tab or we are at a tab stop,
  966.            delete a char forword            */
  967.         if (curwp->w_bufp->b_mode & MDOVER &&
  968.             curwp->w_doto < curwp->w_dotp->l_used &&
  969.             (lgetc(curwp->w_dotp, curwp->w_doto) != '\t' ||
  970.              (curwp->w_doto) % 8 == 7))
  971.                 ldelete(1L, FALSE);
  972.  
  973.         /* do the appropriate insertion */
  974.         if (c == '}' && (curbp->b_mode & MDCMOD) != 0)
  975.                 status = insbrace(n, c);
  976.             else if (c == '#' && (curbp->b_mode & MDCMOD) != 0)
  977.                 status = inspound();
  978.             else
  979.                     status = linsert(n, c);
  980.  
  981. #if    CFENCE
  982.         /* check for CMODE fence matching */
  983.         if ((c == '}' || c == ')' || c == ']') &&
  984.                 (curbp->b_mode & MDCMOD) != 0)
  985.             fmatch(c);
  986. #endif
  987.  
  988.                 lastflag = thisflag;
  989.                 return (status);
  990.         }
  991.     TTbeep();
  992.     mlwrite("[Key not bound]");        /* complain        */
  993.         lastflag = 0;                           /* Fake last flags.     */
  994.         return (FALSE);
  995. }
  996.  
  997. /*
  998.  * Fancy quit command, as implemented by Norm. If the any buffer has
  999.  * changed do a write on that buffer and exit emacs, otherwise simply exit.
  1000.  */
  1001. quickexit(f, n)
  1002. {
  1003.     register BUFFER *bp;    /* scanning pointer to buffers */
  1004.     register int status;
  1005.  
  1006.     bp = bheadp;
  1007.     while (bp != NULL) {
  1008.             if ((bp->b_flag&BFCHG) != 0    /* Changed.             */
  1009.             && (bp->b_flag&BFINVS) == 0) {    /* Real.                */
  1010.             curbp = bp;        /* make that buffer cur    */
  1011.             mlwrite("[Saving %s]\n",bp->b_fname);
  1012.                     if ((status = filesave(f, n)) != TRUE)
  1013.                         return(status);
  1014.         }
  1015.     bp = bp->b_bufp;            /* on to the next buffer */
  1016.     }
  1017.         quit(f, n);                             /* conditionally quit   */
  1018. }
  1019.  
  1020. /*
  1021.  * Quit command. If an argument, always quit. Otherwise confirm if a buffer
  1022.  * has been changed and not written out. Normally bound to "C-X C-C".
  1023.  */
  1024. quit(f, n)
  1025. {
  1026.         register int    s;
  1027.  
  1028.         if (f != FALSE                          /* Argument forces it.  */
  1029.         || anycb() == FALSE                     /* All buffers clean.   */
  1030.                         /* User says it's OK.   */
  1031.         || (s=mlyesno("Modified buffers exist. Leave anyway")) == TRUE) {
  1032. #if    FILOCK
  1033.         if (lockrel() != TRUE) {
  1034.             TTputc('\n');
  1035.             TTputc('\r');
  1036.             TTclose();
  1037.             TTkclose();
  1038.             exit(1);
  1039.         }
  1040. #endif
  1041.                 vttidy();
  1042. #if    APROF
  1043.         /* if doing AZTEC C profiling, close up and write it out */
  1044.         monitor(0,0,0,0,0);
  1045. #endif
  1046.                 exit(GOOD);
  1047.         }
  1048.     mlwrite("");
  1049.         return (s);
  1050. }
  1051.  
  1052. /*
  1053.  * Begin a keyboard macro.
  1054.  * Error if not at the top level in keyboard processing. Set up variables and
  1055.  * return.
  1056.  */
  1057. ctlxlp(f, n)
  1058. {
  1059.         if (kbdmode != STOP) {
  1060.                 mlwrite("%%Macro already active");
  1061.                 return(FALSE);
  1062.         }
  1063.         mlwrite("[Start macro]");
  1064.     kbdptr = &kbdm[0];
  1065.     kbdend = kbdptr;
  1066.         kbdmode = RECORD;
  1067.         return (TRUE);
  1068. }
  1069.  
  1070. /*
  1071.  * End keyboard macro. Check for the same limit conditions as the above
  1072.  * routine. Set up the variables and return to the caller.
  1073.  */
  1074. ctlxrp(f, n)
  1075. {
  1076.         if (kbdmode == STOP) {
  1077.                 mlwrite("%%Macro not active");
  1078.                 return(FALSE);
  1079.         }
  1080.     if (kbdmode == RECORD) {
  1081.             mlwrite("[End macro]");
  1082.             kbdmode = STOP;
  1083.     }
  1084.         return(TRUE);
  1085. }
  1086.  
  1087. /*
  1088.  * Execute a macro.
  1089.  * The command argument is the number of times to loop. Quit as soon as a
  1090.  * command gets an error. Return TRUE if all ok, else FALSE.
  1091.  */
  1092. ctlxe(f, n)
  1093. {
  1094.         if (kbdmode != STOP) {
  1095.                 mlwrite("%%Macro already active");
  1096.                 return(FALSE);
  1097.         }
  1098.         if (n <= 0)
  1099.                 return (TRUE);
  1100.     kbdrep = n;        /* remember how many times to execute */
  1101.     kbdmode = PLAY;        /* start us in play mode */
  1102.     kbdptr = &kbdm[0];    /*    at the beginning */
  1103.     return(TRUE);
  1104. }
  1105.  
  1106. /*
  1107.  * Abort.
  1108.  * Beep the beeper. Kill off any keyboard macro, etc., that is in progress.
  1109.  * Sometimes called as a routine, to do general aborting of stuff.
  1110.  */
  1111. ctrlg(f, n)
  1112. {
  1113.         TTbeep();
  1114.     kbdmode = STOP;
  1115.     mlwrite("[Aborted]");
  1116.         return(ABORT);
  1117. }
  1118.  
  1119. /* tell the user that this command is illegal while we are in
  1120.    VIEW (read-only) mode                */
  1121.  
  1122. rdonly()
  1123.  
  1124. {
  1125.     TTbeep();
  1126.     mlwrite("[Key illegal in VIEW mode]");
  1127.     return(FALSE);
  1128. }
  1129.  
  1130. resterr()
  1131.  
  1132. {
  1133.     TTbeep();
  1134.     mlwrite("[That command is RESTRICTED]");
  1135.     return(FALSE);
  1136. }
  1137.  
  1138. meta()    /* dummy function for binding to meta prefix */
  1139. {
  1140. }
  1141.  
  1142. cex()    /* dummy function for binding to control-x prefix */
  1143. {
  1144. }
  1145.  
  1146. unarg()    /* dummy function for binding to universal-argument */
  1147. {
  1148. }
  1149.  
  1150. /*****        Compiler specific Library functions    ****/
  1151.  
  1152. #if    MWC86 & MSDOS
  1153. movmem(source, dest, size)
  1154.  
  1155. char *source;    /* mem location to move memory from */
  1156. char *dest;    /* memory location to move text to */
  1157. int size;    /* number of bytes to move */
  1158.  
  1159. {
  1160.     register int i;
  1161.  
  1162.     for (i=0; i < size; i++)
  1163.         *dest++ = *source++;
  1164. }
  1165. #endif
  1166.  
  1167. #if    RAMSIZE & LATTICE & MSDOS
  1168. /*    These routines will allow me to track memory usage by placing
  1169.     a layer on top of the standard system malloc() and free() calls.
  1170.     with this code defined, the environment variable, $RAM, will
  1171.     report on the number of bytes allocated via malloc.
  1172.  
  1173.     with SHOWRAM defined, the number is also posted on the
  1174.     end of the bottom mode line and is updated whenever it is changed.
  1175. */
  1176.  
  1177. #undef    malloc
  1178. #undef    free
  1179.  
  1180. char *allocate(nbytes)    /* allocate nbytes and track */
  1181.  
  1182. unsigned nbytes;    /* # of bytes to allocate */
  1183.  
  1184. {
  1185.     char *mp;    /* ptr returned from malloc */
  1186.     char *malloc();
  1187.  
  1188.     mp = malloc(nbytes);
  1189.     if (mp) {
  1190.         envram += nbytes;
  1191. #if    RAMSHOW
  1192.         dspram();
  1193. #endif
  1194.     }
  1195.  
  1196.     return(mp);
  1197. }
  1198.  
  1199. release(mp)    /* release malloced memory and track */
  1200.  
  1201. char *mp;    /* chunk of RAM to release */
  1202.  
  1203. {
  1204.     unsigned *lp;    /* ptr to the long containing the block size */
  1205.  
  1206.     if (mp) {
  1207.         lp = ((unsigned *)mp) - 1;
  1208.  
  1209.         /* update amount of ram currently malloced */
  1210.         envram -= (long)*lp - 2;
  1211.         free(mp);
  1212. #if    RAMSHOW
  1213.         dspram();
  1214. #endif
  1215.     }
  1216. }
  1217.  
  1218. #if    RAMSHOW
  1219. dspram()    /* display the amount of RAM currently malloced */
  1220.  
  1221. {
  1222.     char mbuf[20];
  1223.     char *sp;
  1224.  
  1225.     TTmove(term.t_nrow - 1, 70);
  1226. #if    COLOR
  1227.     TTforg(7);
  1228.     TTbacg(0);
  1229. #endif
  1230.     sprintf(mbuf, "[%lu]", envram);
  1231.     sp = &mbuf[0];
  1232.     while (*sp)
  1233.         TTputc(*sp++);
  1234.     TTmove(term.t_nrow, 0);
  1235.     movecursor(term.t_nrow, 0);
  1236. }
  1237. #endif
  1238. #endif
  1239.  
  1240.